using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;

using Deepcode.Flux.Core.Systems.Scheduler;
using Deepcode.Flux.Core.Systems.Audit;

public partial class Public_Schedule_Default : System.Web.UI.Page
{
	/// <summary>
	/// This is the processing script for the scheduled task manager
	/// it can be invoked in a browser to see debug information - add ?debug=1 
	/// to the URL to see debug information.
	/// </summary>
	/// <param name="sender"></param>
	/// <param name="e"></param>
	protected void Page_Load(object sender, EventArgs e)
	{
		bool withOutputs = ((Request["debug"]) != "");

		SystemEvents ev = new SystemEvents();
		Tasks tasks = new Tasks();
		foreach (Task task in tasks.GetDueTasks())
		{
			if( withOutputs ) Response.Write("TASK: " + task.TaskName + " (" + task.Execute + ")<br/>");

			// Invoke the task
			string url = Page.ResolveUrl( task.Execute );
			if( ! url.StartsWith("http") )
				url = String.Format("http://{0}{1}", Page.Request.Url.Host, url );

			try
			{
				// Run the task and retrieve the response.
				System.Net.WebRequest request = System.Net.WebRequest.Create(url);
				System.Net.WebResponse response = request.GetResponse();
				response.Close();

				ev.Raise(
					EventSeverity.Information,
					EventType.System,
					-1,
					"Flux",
					"Scheduled Tasks",
					"Task ({0}) was executed by the scheduled task manager (URL:{1})",
					task.TaskName, task.Execute);
			}
			catch
			{
				// don't update the task - just continue to next task
				if (withOutputs) Response.Write("&nbsp;&nbsp;&nbsp; ^^^^^ TASK FAILED!<br/>");
				ev.Raise(
					EventSeverity.Error,
					EventType.System,
					-1,
					"Flux",
					"Scheduled Tasks",
					"SCHEDULED TASK FAILED! (Task={0}) (URL={1})",
					task.TaskName, task.Execute);

				continue;
			}


			// If it's a once only operation - it's been executed and it's finished
			if (task.Frequency == TaskFrequency.OnceOnly)
			{
				task.Finished = true;
			}
			else
			{
				// Add on the interval for the next execution
				task.ExecuteNext = AddTimescaleToFuture(task.ExecuteNext, task.Frequency, task.Interval);

				// Decrement remaining executions if not unlimited
				if (task.TimesRemaining >= 1) task.TimesRemaining--;
			}
			tasks.Save( task );
		}
	}

	/// <summary>
	/// Adds the specified timescale onto a date until the date is in the future.
	/// </summary>
	/// <param name="sourceDate"></param>
	/// <param name="freq"></param>
	/// <param name="interval"></param>
	/// <returns></returns>
	private System.DateTime AddTimescaleToFuture(System.DateTime sourceDate, TaskFrequency freq, int interval)
	{
		System.DateTime resultDate = sourceDate;
		
		while( resultDate < System.DateTime.Now )
		{
			switch (freq)
			{
				case TaskFrequency.Minute:
					resultDate = resultDate.AddMinutes(interval);
					break;
				case TaskFrequency.Hour:
					resultDate = resultDate.AddHours(interval);
					break;
				case TaskFrequency.Day:
					resultDate = resultDate.AddDays(interval);
					break;
				case TaskFrequency.Month:
					resultDate = resultDate.AddMonths(interval);
					break;
				case TaskFrequency.Year:
					resultDate = resultDate.AddYears(interval);
					break;
				default:
					return sourceDate;
			}
		}
		return resultDate;
	}
}
